﻿using System;
using System.Collections.Generic;
//using System.ComponentModel;
//using System.Data;
//using System.Drawing;
//using System.Linq;
using System.Text;
using System.Threading.Tasks;
//using System.Windows.Forms;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using System.Diagnostics;

namespace MyRTS
{
    public class NewModel
    {
        public Vector3 Translation = new Vector3(0, 0, 0);
        public Vector3 RotationAroundAxis = new Vector3(0, 0, 0);
        public List<Vector3> Vertices = new List<Vector3>();
        public List<Vector3> Normals = new List<Vector3>();
        public List<int> VertexIndex = new List<int>();
        public List<Vector2> UV=new List<Vector2>();
        public List<int> UVIndex = new List<int>();
        public List<string[]> Properies = new List<string[]>();
        public BeginMode Mode = BeginMode.Triangles;
        public string NormalsMode;
        public string UVMode;
        public string name;
        public int positionVboHandle;
        public int eboHandle;
        public int normalVboHandle;
        public int vaoHandle;
        public int shaderProgramHandle;

        public NewModel(Node m, int shadowprogram)
        {
            name = m.PropertyList[0].Datas;
            shaderProgramHandle = shadowprogram;
            foreach (Node n in m.NodeList)
            {
                if (n.name == "Vertices")
                {
                    int k = 0;
                    float[] tem = new float[3];
                    for (int i = 0; i < n.PropertyList.Count; i++)
                    {
                        if (n.PropertyList[i].type == "D")
                        {
                            tem[k] = (float)Convert.ToDouble(n.PropertyList[i].Datas);
                            k++;
                            if (k > 2)
                            {
                                Vector3 temv = new Vector3(tem[0],tem[1],tem[2]);
                                Vertices.Add(temv);
                                k = 0;
                            }
                        }

                    }

                }
                if (n.name == "PolygonVertexIndex")
                {
                    if (Convert.ToInt32(n.PropertyList[2].Datas) > 0)
                    {
                        Mode = BeginMode.Points;
                    }
                    for (int i = 0; i < n.PropertyList.Count; i++)
                    {
                        if (n.PropertyList[i].type == "I")
                        {
                            int tem = Convert.ToInt32(n.PropertyList[i].Datas);
                            if (tem < 0)
                            {
                                tem = -(tem + 1);
                            }
                            VertexIndex.Add(tem);
                        }
                    }
                  
                }

                if (n.name == "LayerElementNormal")
                {
                    foreach (Node o in n.NodeList)
                    {
                        if (o.name=="MappingInformationType")
                        {
                            NormalsMode = o.PropertyList[0].Datas;
                      
                        }
                        if (o.name == "Normals")
                        {
                            int k = 0;
                            float[] tem = new float[3];
                            for (int i = 0; i < o.PropertyList.Count; i++)
                            {
                                if (o.PropertyList[i].type == "D")
                                {
                                    tem[k] = (float)Convert.ToDouble(o.PropertyList[i].Datas);
                                    k++;
                                    if (k > 2)
                                    {
                                        Vector3 temv = new Vector3(tem[0], tem[1], tem[2]);
                                        Normals.Add(Vector3.Normalize(temv));
                                        k = 0;
                                    }
                                }

                            }
                            
                        }
                        
                    }
                }

                if (n.name == "LayerElementUV")
                {
                    foreach (Node o in n.NodeList)
                    {
                        if (o.name == "MappingInformationType")
                        {
                            UVMode = o.PropertyList[0].Datas;
                           
                        }
                        if (o.name == "UV")
                        {

                            int k = 0;
                            float[] tem = new float[3];
                            for (int i = 0; i < o.PropertyList.Count; i++)
                            {
                                if (o.PropertyList[i].type == "D")
                                {
                                    tem[k] = (float)Convert.ToDouble(o.PropertyList[i].Datas);
                                    k++;
                                    if (k > 1)
                                    {
                                        Vector2 temv = new Vector2(tem[0], tem[1]);
                                        UV.Add(temv);
                                        k = 0;
                                    }
                                }

                            }

                          

                        }
                        if (o.name == "UVIndex")
                        {
                           
                            for (int i = 0; i < o.PropertyList.Count; i++)
                            {
                                if (o.PropertyList[i].type == "I")
                                {
                                    int tem = Convert.ToInt32(o.PropertyList[i].Datas);
                                   
                                    UVIndex.Add(tem);
                                }
                            }
                           
                        }
                    }
           
                }
                if (n.name.Contains("Properties"))
                {
                    foreach (Node o in n.NodeList)
                    {
                        string[] tem = new string[o.PropertyList.Count];
                        for (int i = 0; i < o.PropertyList.Count; i++)
                        {
                            tem[i] = o.PropertyList[i].Datas;
                        }
                        Properies.Add(tem);

                    }
                
                }


            }
            CrateBuffors2();

        }

        public void ProcessBuffors()
        {

        }

        public  void CrateBuffors()
        {


            Vector3[] Vertexs = Vertices.ToArray();
            int[] vertexIndex = VertexIndex.ToArray();

            
            

            GL.GenBuffers(1, out positionVboHandle);
            GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle);
            GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,
                new IntPtr(Vertexs.Length * Vector3.SizeInBytes),
                Vertexs, BufferUsageHint.StaticDraw);

            
            GL.GenBuffers(1, out eboHandle);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, eboHandle);
            GL.BufferData(BufferTarget.ElementArrayBuffer,
                new IntPtr(sizeof(uint) * vertexIndex.Length),
                vertexIndex, BufferUsageHint.StaticDraw);
             


            GL.GenBuffers(1, out normalVboHandle);
            GL.BindBuffer(BufferTarget.ArrayBuffer, normalVboHandle);

            if (NormalsMode == "ByVertice")
            {
                Vector3[] Normalss = Normals.ToArray();
                GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,
                        new IntPtr(Normalss.Length * Vector3.SizeInBytes),
                        Normalss, BufferUsageHint.StaticDraw);
            }
            else
            {
                if (NormalsMode == "ByPolygonVertex")
                {
                    List<Vector3> nnorm = new List<Vector3>();
                    Vector3[] nnorm1 = new Vector3[Vertices.Count];
                    for (int i = 0; i < VertexIndex.Count; i++)
                    {

                        Vector3 tem = new Vector3(Normals[i]);
                        nnorm1[VertexIndex[i]] = tem;

                            nnorm.Add(tem);
                        

                    }
                 
                    GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,
                        new IntPtr(nnorm1.Length * Vector3.SizeInBytes),
                        nnorm1, BufferUsageHint.StaticDraw);
               //     GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,
           //     new IntPtr(Vertexs.Length * Vector3.SizeInBytes),
            //    Vertexs, BufferUsageHint.StaticDraw);
                    int pt = 0;
                }

            }

            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);


            GL.GenVertexArrays(1, out vaoHandle);
            GL.BindVertexArray(vaoHandle);

            GL.EnableVertexAttribArray(0);
            GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle);
            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, 0);
            GL.BindAttribLocation(shaderProgramHandle, 0, "in_position");

            GL.EnableVertexAttribArray(1);
            GL.BindBuffer(BufferTarget.ArrayBuffer, normalVboHandle);
            GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, 0);
            GL.BindAttribLocation(shaderProgramHandle, 1, "in_normal");

            GL.BindBuffer(BufferTarget.ElementArrayBuffer, eboHandle);

            GL.BindVertexArray(0);




        }

        public void CrateBuffors2()
        {
            int[] nvi = new int[VertexIndex.Count];
            List<Vector3> nv = new List<Vector3>();
            for (int i = 0; i < VertexIndex.Count; i++)
            {
                nvi[i] = i;
                Vector3 tem = new Vector3(Vertices[VertexIndex[i]]);
                nv.Add(tem);

            }

            Vector3[] Vertexs = nv.ToArray();


            int[] vertexIndex = nvi;




            GL.GenBuffers(1, out positionVboHandle);
            GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle);
            GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,
                new IntPtr(Vertexs.Length * Vector3.SizeInBytes),
                Vertexs, BufferUsageHint.StaticDraw);


            GL.GenBuffers(1, out eboHandle);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, eboHandle);
            GL.BufferData(BufferTarget.ElementArrayBuffer,
                new IntPtr(sizeof(uint) * vertexIndex.Length),
                vertexIndex, BufferUsageHint.StaticDraw);



            GL.GenBuffers(1, out normalVboHandle);
            GL.BindBuffer(BufferTarget.ArrayBuffer, normalVboHandle);

            if (NormalsMode == "ByVertice")
            {

                List<Vector3> nvn = new List<Vector3>();
                for (int i = 0; i < VertexIndex.Count; i++)
                {
                 
                    Vector3 tem = new Vector3(Normals[VertexIndex[i]]);
                    nvn.Add(tem);

                }

                Vector3[] Normalss = nvn.ToArray();
                GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,
                        new IntPtr(Normalss.Length * Vector3.SizeInBytes),
                        Normalss, BufferUsageHint.StaticDraw);
            }
            else
            {
                if (NormalsMode == "ByPolygonVertex")
                {
                    Vector3[] Normalss = Normals.ToArray();
                    GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,
                            new IntPtr(Normalss.Length * Vector3.SizeInBytes),
                            Normalss, BufferUsageHint.StaticDraw);
                }

            }

            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);


            GL.GenVertexArrays(1, out vaoHandle);
            GL.BindVertexArray(vaoHandle);

            GL.EnableVertexAttribArray(0);
            GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle);
            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, 0);
            GL.BindAttribLocation(shaderProgramHandle, 0, "in_position");

            GL.EnableVertexAttribArray(1);
            GL.BindBuffer(BufferTarget.ArrayBuffer, normalVboHandle);
            GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, 0);
            GL.BindAttribLocation(shaderProgramHandle, 1, "in_normal");

            GL.BindBuffer(BufferTarget.ElementArrayBuffer, eboHandle);

            GL.BindVertexArray(0);




        }
    }
}